<!DOCTYPE html>
<html lang="en-us">
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
<meta charset="UTF-8">
<title>Types and Mappings | Elasticsearch: The Definitive Guide [2.x] | Elastic</title>
<link rel="home" href="index.html" title="Elasticsearch: The Definitive Guide [2.x]">
<link rel="up" href="index-management.html" title="Index Management">
<link rel="prev" href="custom-analyzers.html" title="Custom Analyzers">
<link rel="next" href="root-object.html" title="The Root Object">
<meta name="DC.type" content="Learn/Docs/Legacy/Elasticsearch/Definitive Guide/2.x">
<meta name="DC.subject" content="Elasticsearch">
<meta name="DC.identifier" content="2.x">
<meta name="robots" content="noindex,nofollow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.optimizely.com/js/18132920325.js"></script>
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/manifest.json">
    <meta name="apple-mobile-web-app-title" content="Elastic">
    <meta name="application-name" content="Elastic">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/mstile-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta name="naver-site-verification" content="936882c1853b701b3cef3721758d80535413dbfd">
    <meta name="yandex-verification" content="d8a47e95d0972434">
    <meta name="localized" content="true">
    <meta name="st:robots" content="follow,index">
    <meta property="og:image" content="https://www.elastic.co/static/images/elastic-logo-200.png">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon-precomposed" sizes="64x64" href="/favicon_64x64_16bit.png">
    <link rel="apple-touch-icon-precomposed" sizes="32x32" href="/favicon_32x32.png">
    <link rel="apple-touch-icon-precomposed" sizes="16x16" href="/favicon_16x16.png">
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/guide/static/styles.css">
  </head>

  <!--© 2015-2021 Elasticsearch B.V. Copying, publishing and/or distributing without written permission is strictly prohibited.-->

  <body>
    <!-- Google Tag Manager -->
    <script>dataLayer = [];</script><noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-58RLH5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-58RLH5');</script>
    <!-- End Google Tag Manager -->

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-12395217-16"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'UA-12395217-16');
    </script>

    <!--BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET-->
    <script type="text/javascript">
      (function(){var g=function(e,h,f,g){
      this.get=function(a){for(var a=a+"=",c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];" "==d.charAt(0);)d=d.substring(1,d.length);if(0==d.indexOf(a))return d.substring(a.length,d.length)}return null};
      this.set=function(a,c){var b="",b=new Date;b.setTime(b.getTime()+6048E5);b="; expires="+b.toGMTString();document.cookie=a+"="+c+b+"; path=/; "};
      this.check=function(){var a=this.get(f);if(a)a=a.split(":");else if(100!=e)"v"==h&&(e=Math.random()>=e/100?0:100),a=[h,e,0],this.set(f,a.join(":"));else return!0;var c=a[1];if(100==c)return!0;switch(a[0]){case "v":return!1;case "r":return c=a[2]%Math.floor(100/c),a[2]++,this.set(f,a.join(":")),!c}return!0};
      this.go=function(){if(this.check()){var a=document.createElement("script");a.type="text/javascript";a.src=g;document.body&&document.body.appendChild(a)}};
      this.start=function(){var a=this;window.addEventListener?window.addEventListener("load",function(){a.go()},!1):window.attachEvent&&window.attachEvent("onload",function(){a.go()})}};
      try{(new g(100,"r","QSI_S_ZN_emkP0oSe9Qrn7kF","https://znemkp0ose9qrn7kf-elastic.siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=ZN_emkP0oSe9Qrn7kF")).start()}catch(i){}})();
    </script><div id="ZN_emkP0oSe9Qrn7kF"><!--DO NOT REMOVE-CONTENTS PLACED HERE--></div>
    <!--END WEBSITE FEEDBACK SNIPPET-->

    <div id="elastic-nav" style="display:none;"></div>
    <script src="https://www.elastic.co/elastic-nav.js"></script>

    <!-- Subnav -->
    <div>
      <div>
        <div class="tertiary-nav d-none d-md-block">
          <div class="container">
            <div class="p-t-b-15 d-flex justify-content-between nav-container">
              <div class="breadcrum-wrapper"><span><a href="/guide/" style="font-size: 14px; font-weight: 600; color: #000;">Docs</a></span></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-container">
      <section id="content">
        <div class="content-wrapper">

          <section id="guide" lang="en">
            <div class="container">
              <div class="row">
                <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                  <!-- start body -->
                  <div class="page_header">
<p>
  <strong>WARNING</strong>: The 2.x versions of Elasticsearch have passed their
  <a href="https://www.elastic.co/support/eol">EOL dates</a>. If you are running
  a 2.x version, we strongly advise you to upgrade.
</p>
<p>
  This documentation is no longer maintained and may be removed. For the latest
  information, see the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">current
  Elasticsearch documentation</a>.
</p>
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: The Definitive Guide [2.x]</a></span>
»
<span class="breadcrumb-link"><a href="getting-started.html">Getting Started</a></span>
»
<span class="breadcrumb-link"><a href="index-management.html">Index Management</a></span>
»
<span class="breadcrumb-node">Types and Mappings</span>
</div>
<div class="navheader">
<span class="prev">
<a href="custom-analyzers.html">« Custom Analyzers</a>
</span>
<span class="next">
<a href="root-object.html">The Root Object »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="mapping"></a>Types and Mappings<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/070_Index_Mgmt/25_Mappings.asciidoc">edit</a>
</h2>
</div></div></div>
<p>A <em>type</em> in Elasticsearch represents a class of similar documents. A type
consists of a <em>name</em>—such as <code class="literal">user</code> or <code class="literal">blogpost</code>—and a <em>mapping</em>. The
mapping, like a database schema, describes the fields or <em>properties</em> that
documents of that type may have, the datatype of each field—​such as <code class="literal">string</code>,
<code class="literal">integer</code>, or <code class="literal">date</code>—and how those fields should be indexed and stored by
Lucene.</p>
<p>Types can be useful abstractions for partitioning similar-but-not-identical data.
But due to how Lucene operates they come with some restrictions.</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_how_lucene_sees_documents"></a>How Lucene Sees Documents<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/070_Index_Mgmt/25_Mappings.asciidoc">edit</a>
</h3>
</div></div></div>
<p>A document in Lucene consists of a simple list of field-value pairs. A field
must have at least one value, but any field can contain multiple values.
Similarly, a single string value may be converted into multiple values by the
analysis process.  Lucene doesn’t care if the values are strings or numbers or
dates—​all values are just treated as <em>opaque bytes</em>.</p>
<p>When we index a document in Lucene, the values for each field are added to the
inverted index for the associated field.  Optionally, the original values may
also be <em>stored</em> unchanged so that they can be retrieved later.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_how_types_are_implemented"></a>How Types Are Implemented<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/070_Index_Mgmt/25_Mappings.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Elasticsearch types are implemented on top of this simple foundation. An index
may have several types, and documents of any of these types may be stored in the same index.</p>
<p>Because Lucene has no concept of document types, the type name of each
document is stored with the document in a metadata field called <code class="literal">_type</code>. When
we search for documents of a particular type, Elasticsearch simply uses a
filter on the <code class="literal">_type</code> field to restrict results to documents of that type.</p>
<p>Lucene also has no concept of mappings. Mappings are the layer
that Elasticsearch uses to <em>map</em> complex JSON documents into the
simple flat documents that Lucene expects to receive.</p>
<p>For instance, the mapping for the <code class="literal">name</code> field in the <code class="literal">user</code> type may declare
that the field is a <code class="literal">string</code> field, and that its value should be analyzed
by the <code class="literal">whitespace</code> analyzer before being indexed into the inverted
index called <code class="literal">name</code>:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">"name": {
    "type":     "string",
    "analyzer": "whitespace"
}</pre>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_avoiding_type_gotchas"></a>Avoiding Type Gotchas<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/070_Index_Mgmt/25_Mappings.asciidoc">edit</a>
</h3>
</div></div></div>
<p>This leads to an interesting thought experiment: what happens if you have two
different types, each with an identically named field but mapped differently
(e.g. one is a string, the other is a number)?</p>
<p>Well, the short answer is that bad things happen and Elasticsearch won’t allow you
to define this mapping at all.  You’d receive an exception when attempting to
configure the mapping.</p>
<p>The longer answer is that each Lucene index contains a single, flat schema
for all fields.  A particular field is either mapped as a string, or a number, but
not both.  And because types are a mechanism added by Elasticsearch <em>on top</em>
of Lucene (in the form of a metadata <code class="literal">_type</code> field), all types in Elasticsearch
ultimately share the same mapping.</p>
<p>Take for example this mapping of two types in the <code class="literal">data</code> index:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
   "data": {
      "mappings": {
         "people": {
            "properties": {
               "name": {
                  "type": "string",
               },
               "address": {
                  "type": "string"
               }
            }
         },
         "transactions": {
            "properties": {
               "timestamp": {
                  "type": "date",
                  "format": "strict_date_optional_time"
               },
               "message": {
                  "type": "string"
               }
            }
         }
      }
   }
}</pre>
</div>
<p>Each type defines two fields (<code class="literal">"name"</code>/<code class="literal">"address"</code> and <code class="literal">"timestamp"</code>/<code class="literal">"message"</code>
respectively).  It may look like they are independent, but under the covers Lucene
will create a single mapping which would look something like this:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
   "data": {
      "mappings": {
        "_type": {
          "type": "string",
          "index": "not_analyzed"
        },
        "name": {
          "type": "string"
        }
        "address": {
          "type": "string"
        }
        "timestamp": {
          "type": "long"
        }
        "message": {
          "type": "string"
        }
      }
   }
}</pre>
</div>
<p><em>Note: This is not actually valid mapping syntax, just used for demonstration</em></p>
<p>The mappings are essentially <em>flattened</em> into a single, global schema for the
entire index.  And that’s why two types cannot define conflicting fields:
Lucene wouldn’t know what to do when the mappings are flattened together.</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_type_takeaways"></a>Type Takeaways<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/070_Index_Mgmt/25_Mappings.asciidoc">edit</a>
</h3>
</div></div></div>
<p>So what’s the takeaway from this discussion?  Technically, multiple types
may live in the same index as long as their fields do not conflict (either because
the fields are mutually exclusive, or because they share identical fields).</p>
<p>Practically though, the important lesson is this:  types are useful when you need
to discriminate between different segments of a single collection. The overall "shape" of the
data is identical (or nearly so) between the different segments.</p>
<p>Types are not as well suited for <em>entirely different types of data</em>.  If your two
types have mutually exclusive sets of fields, that means half your index is going to
contain "empty" values (the fields will be <em>sparse</em>), which will eventually cause performance
problems.  In these cases, it’s much better to utilize two independent indices.</p>
<p>In summary:</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<span class="strong strong"><strong>Good:</strong></span> <code class="literal">kitchen</code> and <code class="literal">lawn-care</code> types inside the <code class="literal">products</code> index, because
the two types are essentially the same schema.
</li>
<li class="listitem">
<span class="strong strong"><strong>Bad:</strong></span> <code class="literal">products</code> and <code class="literal">logs</code> types inside the <code class="literal">data</code> index, because the two types are
mutually exclusive.  Separate these into their own indices.
</li>
</ul>
</div>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="custom-analyzers.html">« Custom Analyzers</a>
</span>
<span class="next">
<a href="root-object.html">The Root Object »</a>
</span>
</div>
</div>

                  <!-- end body -->
                </div>
                <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                  <div id="rtpcontainer" style="display: block;">
                    <div class="mktg-promo">
                      <h3>Most Popular</h3>
                      <ul class="icons">
                        <li class="icon-elasticsearch-white"><a href="https://www.elastic.co/webinars/getting-started-elasticsearch?baymax=default&amp;elektra=docs&amp;storm=top-video">Get Started with Elasticsearch: Video</a></li>
                        <li class="icon-kibana-white"><a href="https://www.elastic.co/webinars/getting-started-kibana?baymax=default&amp;elektra=docs&amp;storm=top-video">Intro to Kibana: Video</a></li>
                        <li class="icon-logstash-white"><a href="https://www.elastic.co/webinars/introduction-elk-stack?baymax=default&amp;elektra=docs&amp;storm=top-video">ELK for Logs &amp; Metrics: Video</a></li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

        </div>


<div id="elastic-footer"></div>
<script src="https://www.elastic.co/elastic-footer.js"></script>
<!-- Footer Section end-->

      </section>
    </div>

<script src="/guide/static/jquery.js"></script>
<script type="text/javascript" src="/guide/static/docs.js"></script>
<script type="text/javascript">
  window.initial_state = {}</script>
  </body>
</html>
